package com.hello.system.service.impl;

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.hello.common.core.web.domain.AjaxResult;
import com.hello.system.service.IWxPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信支付服务实现
 * 
 * @author hello
 */
@Service
@Slf4j
public class WxPayServiceImpl implements IWxPayService {

    @Autowired
    private WxPayService wxPayService;

    @Override
    public Map<String, Object> createOrder(String orderId, BigDecimal amount, String description, String openid, String clientIp) {
        try {
            log.info("创建支付订单, 订单号: {}, 金额: {}, 描述: {}, openid: {}, 客户端IP: {}", 
                    orderId, amount, description, openid, clientIp);
            
            // 构建统一下单请求参数
            WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
            request.setBody(description);
            request.setOutTradeNo(orderId);
            
            // 将元转为分
            int amountCent = amount.multiply(new BigDecimal("100")).intValue();
            request.setTotalFee(amountCent);
            
            request.setOpenid(openid);
            request.setTradeType(WxPayConstants.TradeType.JSAPI);
            
            // 设置终端IP，使用传入的客户端IP或默认值
            request.setSpbillCreateIp(clientIp != null && !clientIp.isEmpty() ? clientIp : "127.0.0.1");
            
            // 调用统一下单接口
            WxPayMpOrderResult result = wxPayService.createOrder(request);
            
            // 返回小程序调用支付需要的参数
            Map<String, Object> payParams = new HashMap<>();
            payParams.put("appId", result.getAppId());
            payParams.put("timeStamp", result.getTimeStamp());
            payParams.put("nonceStr", result.getNonceStr());
            payParams.put("package", result.getPackageValue());
            payParams.put("signType", result.getSignType());
            payParams.put("paySign", result.getPaySign());
            
            log.info("创建支付订单成功, 订单号: {}", orderId);
            return payParams;
        } catch (WxPayException e) {
            log.error("创建支付订单失败", e);
            throw new RuntimeException("创建支付订单失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> createOrder(String orderId, BigDecimal amount, String description, String openid) {
        return createOrder(orderId, amount, description, openid, "127.0.0.1");
    }

    @Override
    public Map<String, Object> queryOrder(String orderId) {
        try {
            log.info("查询订单, 订单号: {}", orderId);
            
            WxPayOrderQueryResult result = wxPayService.queryOrder(null, orderId);
            
            Map<String, Object> orderInfo = new HashMap<>();
            orderInfo.put("orderId", result.getOutTradeNo());
            orderInfo.put("transactionId", result.getTransactionId());
            orderInfo.put("tradeState", result.getTradeState());
            orderInfo.put("totalFee", result.getTotalFee());
            orderInfo.put("timeEnd", result.getTimeEnd());
            
            log.info("查询订单成功, 订单号: {}, 交易状态: {}", orderId, result.getTradeState());
            return orderInfo;
        } catch (WxPayException e) {
            log.error("查询订单失败", e);
            throw new RuntimeException("查询订单失败: " + e.getMessage());
        }
    }

    @Override
    public String parseOrderNotification(String notifyData) {
        try {
            log.info("收到支付结果通知");
            
            // 解析支付结果通知
            WxPayOrderNotifyResult result = wxPayService.parseOrderNotifyResult(notifyData);
            
            // 判断支付结果
            if (WxPayConstants.ResultCode.SUCCESS.equals(result.getResultCode())) {
                String orderId = result.getOutTradeNo();
                String transactionId = result.getTransactionId();
                Integer totalFee = result.getTotalFee();
                
                log.info("支付成功, 订单号: {}, 微信支付单号: {}, 支付金额: {}分", orderId, transactionId, totalFee);
                
                // TODO: 更新订单状态为已支付
                // 在实际应用中，这里应该调用订单服务，更新订单状态
                
                // 返回成功响应给微信，避免重复通知
                return WxPayNotifyResponse.success("处理成功");
            } else {
                log.error("支付失败: {}", result.getErrCodeDes());
                return WxPayNotifyResponse.fail(result.getErrCodeDes());
            }
        } catch (WxPayException e) {
            log.error("解析支付通知失败", e);
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }

    @Override
    public Map<String, Object> refund(String orderId, String refundId, BigDecimal amount, BigDecimal totalAmount, String reason) {
        try {
            log.info("申请退款, 订单号: {}, 退款单号: {}, 退款金额: {}, 原订单金额: {}, 退款原因: {}", 
                    orderId, refundId, amount, totalAmount, reason);
            
            WxPayRefundRequest request = new WxPayRefundRequest();
            request.setOutTradeNo(orderId);
            request.setOutRefundNo(refundId);
            
            // 将元转为分
            int refundCent = amount.multiply(new BigDecimal("100")).intValue();
            int totalCent = totalAmount.multiply(new BigDecimal("100")).intValue();
            
            request.setRefundFee(refundCent);
            request.setTotalFee(totalCent);
            request.setRefundDesc(reason);
            
            WxPayRefundResult result = wxPayService.refund(request);
            
            Map<String, Object> refundInfo = new HashMap<>();
            refundInfo.put("refundId", result.getRefundId());
            refundInfo.put("outRefundNo", result.getOutRefundNo());
            refundInfo.put("refundFee", result.getRefundFee());
            refundInfo.put("refundStatus", "processing");
            
            log.info("申请退款成功, 订单号: {}, 退款单号: {}", orderId, refundId);
            return refundInfo;
        } catch (WxPayException e) {
            log.error("申请退款失败", e);
            throw new RuntimeException("申请退款失败: " + e.getMessage());
        }
    }
} 